home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / NTUMIN10.ARJ / LOGMIN_G.C < prev    next >
C/C++ Source or Header  |  1992-03-12  |  15KB  |  445 lines

  1. /****************************************************************************
  2.  *
  3.  *      Program name : LOGMIN_G.C
  4.  *
  5.  *    Written By : Eng-Huat Ong and Kian-Mong Low.
  6.  *
  7.  *      This is the actual minimization algorithm. Variation from the actual
  8.  *    LOGMIN algorithm is as follows:
  9.  *        1.    Minterms with adjacency 0 or 1 is minimised first
  10.  *        2.    Select next minterm with lowest adjacency wrt b-array
  11.  *        3.  If more than 1 such minterms, select one with the lowest
  12.  *            adjacency wrt to a-array
  13.  *        4.    To shrink the CPT, select an adjacent term, mi that has the
  14.  *            largest wi AND is already covered
  15.  *        5.  If more than one such adjacent terms are covered, select one
  16.  *        with the lowest adjacency wrt to b-array
  17.  *        6.  If non of the adjacent term is covered, select one with the
  18.  *        lowest adjacency wrt b-array from the uncovered adj term
  19.  *        at step 4.
  20.  *
  21.  * --------------------------------------------------------------------------
  22.  *    Copyright (c) 1992. All Rights Reserved. Nanyang Technological
  23.  *    University.
  24.  *
  25.  *    You are free to use, copy and distribute this software and its
  26.  *    documentation providing that:
  27.  *
  28.  *        NO FEE IS CHARGED FOR USE, COPYING OR DISTRIBUTION.
  29.  *
  30.  *        IT IS NOT MODIFIED IN ANY WAY.
  31.  *
  32.  *        THE COPYRIGHT NOTICE APPEAR IN ALL COPIES.
  33.  *
  34.  *    This program is provided "AS IS" without any warranty, expressed or
  35.  *    implied, including but not limited to fitness for any particular
  36.  *    purpose.
  37.  *
  38.  *    If you find NTUMIN fast, easy, and useful, a note or comment would be
  39.  *    appreciated. Please send to:
  40.  *
  41.  *        Boon-Tiong Tan or Othman Bin Ahmad
  42.  *        School of EEE
  43.  *        Nanyang Technological University
  44.  *        Nanyang Avenue
  45.  *        Singapore 2263
  46.  *        Republic of Singapore
  47.  *
  48.  ***************************************************************************/
  49.  
  50. #include <stdio.h>
  51. #include <stdlib.h>
  52. #include <string.h>
  53. #define mask8 255
  54.  
  55. unsigned char   *logmin_g(a, b)              /* pointer to a & b array passed */
  56. unsigned char   *a, *b;
  57.  
  58. {
  59.    unsigned short   pterm, ma, mb, *pm, *pm1, *point, pos, pos1;
  60.    unsigned  long   m, k, topow();
  61.    register  long   i, wo, wi;
  62.    register  char   j;
  63.          char   test;
  64.    unsigned  char   *c, *d, *e, *s, *temp, count, adj0, adji;
  65.    unsigned  char   n, adj, adjacency(), nspm, cover;
  66.    unsigned  char   *adjacent(), *reduce(), *cpt(), *ssm(), adj_of_mi();
  67.  
  68.  
  69.    mb = *(b+2)<<8 | *(b+1);            /* no. of minterms in b-array */
  70.  
  71.    n    = *a;                          /* no. of variables */
  72.    nspm = *(a+3);                      /* no. of bytes/minterm */
  73.    ma = *(a+2)<<8 | *(a+1);            /* no. of minterms in a-array */
  74.  
  75.    temp = (unsigned char *) malloc(nspm+1);        /* temporary storage */
  76.    if (temp == 0)
  77.       {
  78.      printf("Out of memory -- LOGMIN_G, *temp\n");
  79.      printf("Program terminated - 1\n");
  80.      exit(0);
  81.       }
  82.  
  83.    s = (unsigned char *) malloc(4);                /* header of s-array */
  84.    if (s == 0)
  85.       {
  86.      printf("Out of memory -- LOGMIN_G, *s\n");
  87.      printf("Program terminated - 2\n");
  88.      exit(0);
  89.       }
  90.  
  91.    pterm = 0;                                /* no. of product term */
  92.  
  93.    /***
  94.     ***  MINIMIZE ALL MINTERMS WITH ADJACENCY OF 0 & 1 FIRST
  95.     ***/
  96.  
  97.    for (i=0; i<mb; i++)                      /* for adj = 0 or 1 */
  98.       {
  99.      *b = n;                             /* assign back to n */
  100.  
  101.      memcpy(temp, (b+4+nspm*i), nspm);   /* pick a minterm from b-array */
  102.      c = adjacent(temp, a, 1);           /* obtain the adjacent terms */
  103.      adj = *(c+1);                       /* adjacency of minterm */
  104.  
  105.      if (adj <= 1)                       /* adjacency 0 or 1 */
  106.         {
  107.            d = cpt(c);                   /* generate CPT */
  108.  
  109.            s = (unsigned char *) realloc(s,4+n*(pterm+1));   /* more space */
  110.            if (s == 0)
  111.           {
  112.              printf("Out of memory -- LOGMIN_G, *s\n");
  113.              printf("Program terminated - 3\n");
  114.              exit(0);
  115.           }
  116.            memcpy ((s+4+n*pterm),d,n);   /* add CPT to soln array */
  117.            pterm++;                      /* product term count */
  118.  
  119.            b = reduce(c,b,i);            /* remove minterms covered from b-array */
  120.            i = (char) *b;                /* index pointer of b-array */
  121.            mb = *(b+2)<<8 | *(b+1);      /* value of mb altered in b-array */
  122.  
  123.            free(d);                    /* free pointer */
  124.         }
  125.      free(c);                            /* free pointer */
  126.       }
  127.  
  128.     /***
  129.      ***  MINIMIZE MINTERMS WITH ADJACENCY GREATER THAN 1
  130.      ***/
  131.  
  132.     while (mb > 0)
  133.        {
  134.       adj0 = 255;                     /* max for 8-bit */
  135.  
  136.       *b = n;                         /* assign back to n */
  137.  
  138.       /***
  139.        ***  OBTAIN AN ARRAY, PM OF POSITION OF ADJACENT TERMS WITH THE LOWEST
  140.        ***  ADJACENCY WRT B-ARRAY
  141.        ***/
  142.  
  143.       for (i=0; i<mb; i++)
  144.          {
  145.         memcpy(temp, (b+4+nspm*i), nspm);    /* pick a minterm */
  146.         adji = adjacency(temp, b);           /* adj wrt b-array */
  147.  
  148.         if (adji<adj0)                       /* look for lowest adj */
  149.            {
  150.               if (adj0!=255)                 /* not the 1st term */
  151.              free(pm);
  152.  
  153.               adj0 = adji;                   /* update lowest adj */
  154.               count = 1;                        /* set count to 1 */
  155.               pm = (unsigned short *) malloc(2);   /* space for pos */
  156.               if (pm == 0)
  157.              {
  158.                 printf("Out of memory -- LOGMIN_G, *pm\n");
  159.                 printf("Program terminated - 4\n");
  160.                 exit(0);
  161.              }
  162.               *pm = i;                       /* 1st pos of minterm */
  163.            }
  164.  
  165.         else if (adji==adj0)                 /* adjacency as low */
  166.            {
  167.               count++;                       /* no. of elements in pm-array */
  168.               pm = (unsigned short*) realloc(pm, 2*count);    /* more space */
  169.               if (pm == 0)
  170.              {
  171.                 printf("Out of memory -- LOGMIN_G, *pm\n");
  172.                 printf("Program terminated - 5\n");
  173.                 exit(0);
  174.              }
  175.               *(pm+count-1) = i;             /* elements in pm-array */
  176.            }
  177.          }
  178.  
  179.       if (count==1)                  /* if only 1 element in pm-array */
  180.          pos = *pm;
  181.       else
  182.          {
  183.         /***
  184.          ***  FORM PM-ARRAY, SELECT THE 1ST ADJACENT TERM THAT HAS THE
  185.          ***  LOWEST ADJACENCY WRT A-ARRAY
  186.          ***/
  187.  
  188.         adj0 = 255;                      /* max for 8-bit */
  189.         for (i=0; i<count; i++)          /* do for all in pm-array */
  190.            {
  191.               pos1 = *(pm+i);                     /* pos of minterm */
  192.               memcpy(temp, (b+4+nspm*pos1), nspm);
  193.               adji = adjacency(temp, a);          /* adj wrt a-array */
  194.  
  195.               if (adji<adj0)                      /* new lowest found */
  196.              {
  197.                 adj0 = adji;                  /* update lowest */
  198.                 pos = *(pm+i);                /* position of required minterm */
  199.              }
  200.            }
  201.          }
  202.        free(pm);
  203.  
  204.        memcpy(temp, (b+4+nspm*pos), nspm);       /* pick the required minterm */
  205.  
  206.        /***
  207.         ***  GENERATE SSM AND TEST FOR COVERAGE BY FUNCTION
  208.         ***/
  209.  
  210.        c = adjacent(temp, a, 255);          /* obtain adjacent terms */
  211.        adj = *(c+1);                        /* adjacency of minterms */
  212.        d = cpt(c);                          /* generate CPT */
  213.        e = ssm(d);                          /* generate SSM */
  214.        m = topow(*(e+1));                   /* no. of SSM terms */
  215.  
  216.        for (j=0; j<m; j++)                  /* check for SSM coverage */
  217.           {
  218.          memcpy (temp, (e+4+nspm*j), nspm);
  219.          test = exist (temp, a, ma);
  220.          if (test == -1)                /* SSM term not in a-array */
  221.              break;
  222.           }
  223.  
  224.        /***
  225.         ***  ALL SSM COVERED BY THE FUNCTION, SELECT CPT AS PRODUCT TERM
  226.         ***/
  227.  
  228.        if (test == 0)                       /* all SSM's covered by fn */
  229.           {
  230.          if (m > 65536)                 /* too many SSM terms */
  231.             {
  232.                printf("Product Term Too Huge \n");
  233.                printf("Program terminated \n");
  234.                exit(0);
  235.             }
  236.          *(e+1) = (m-1) & mask8;        /* no. of SSM terms minus 1 */
  237.          *(e+2) = (m-1)>>8 & mask8;
  238.          b = reduce(e,b,i);             /* remove minterms covered from b-array */
  239.          mb = *(b+2)<<8 | *(b+1);       /* no. of minterms in b-array */
  240.  
  241.          s = (unsigned char *) realloc(s, 4+n*(pterm+1)); /* more space */
  242.          if (s == 0)
  243.             {
  244.                printf("Out of memory -- LOGMIN_G, *s\n");
  245.                printf("Program terminated - 6\n");
  246.                exit(0);
  247.             }
  248.          memcpy((s+4+n*pterm),d,n);     /* add CPT to soln array */
  249.          pterm++;                       /* no. of product terms */
  250.  
  251.          free(d);                       /* free pointers */
  252.          free(e);
  253.           }
  254.        else
  255.           {
  256.          /***
  257.           ***  SSM NOT COVERED BY THE FUNCTION
  258.           ***/
  259.  
  260.          free(d);                       /* free pointer */
  261.          cover =0;                      /* coverage status */
  262.  
  263.          while (!cover)        /* do until shrinked SSM is covered */
  264.             {
  265.                /***
  266.             ***  OBTAIN AN ARRAY, PM OF POSITIONS OF ADJACENT TERMS, MI WITH THE LARGEST WI
  267.             ***/
  268.  
  269.                wo = -1;                        /* initial value */
  270.                for (j=0; j<adj; j++)           /* do for all adjacent terms */
  271.               {
  272.                  memcpy(temp,(c+4+nspm*(j+1)),nspm); /* pick adjacent term */
  273.  
  274.                  wi = adj_of_mi(temp,e,a);           /* obtain wi */
  275.                  if (wi>wo)
  276.                 {
  277.                    if (wo != -1)                 /* not the first */
  278.                       free(pm);
  279.                    wo = wi;                      /* new lowest value */
  280.                    count = 1;                    /* reset count to 1 */
  281.  
  282.                    pm = (unsigned short *) malloc(2);  /* space for pm */
  283.                    if (pm==0)
  284.                       {
  285.                      printf("Out of memory -- LOGMIN_G, *pm\n");
  286.                      printf("Program terminated - 7\n");
  287.                      exit(0);
  288.                       }
  289.                    *pm = j;                      /* first element */
  290.                 }
  291.                  else if (wi==wo)                    /* wi as large */
  292.                 {
  293.                    count++;                      /* no. of element in pm-array */
  294.  
  295.                    pm = (unsigned short *) realloc (pm, 2*count);  /* more space */
  296.                    if (pm==0)
  297.                       {
  298.                      printf("Out of memory -- LOGMIN_G, *pm\n");
  299.                      printf("Program terminated - 8\n");
  300.                      exit(0);
  301.                       }
  302.                    *(pm+count-1) = j;            /* elements of pm-array */
  303.                 }
  304.               }
  305.                free(e);                                  /* free pointer */
  306.  
  307.                /***
  308.             ***  DETERMINE FROM PM-ARRAY, AN ARRAY, PM1 OF POSITION OF ADJACENT TERMS
  309.             ***  THAT HAVE ALREADY BEEN COVERED
  310.             ***/
  311.  
  312.                pm1 = (unsigned short *) malloc(2);       /* space for pm1 */
  313.                if (pm1==0)
  314.               {
  315.                  printf("Out of memory -- LOGMIN_G, *pm1\n");
  316.                  printf("Program terminated - 9\n");
  317.                  exit(0);
  318.               }
  319.  
  320.                k = 0;
  321.                for (j=0; j<count; j++)              /* do for all element in pm-array */
  322.               {
  323.                  memcpy(temp, (c+4+nspm*(1+ *(pm+j))), nspm);    /* pick adj term */
  324.                  test = exist(temp,b,mb);
  325.                  if (test == -1)                               /* already covered */
  326.                 {
  327.                    memcpy((pm1+k++), (pm+j), 2);       /* transfer pos to pm1 */
  328.  
  329.                    pm1 = (unsigned short *) realloc(pm1, 2*(k+1)); /*  more space */
  330.                    if (pm1==0)
  331.                       {
  332.                      printf("Out of memory -- LOGMIN_G, *pm1\n");
  333.                      printf("Program terminated - 10\n");
  334.                      exit(0);
  335.                       }
  336.                 }
  337.               }
  338.  
  339.                /***
  340.             ***  SELECT FROM PM1-ARRAY (IF EMPTY, SELECT FROM PM-ARRAY),
  341.             ***  THE 1ST ADJACENT TERM, MI WITH THE LOWEST ADJACENCY WRT B-ARRAY
  342.             ***/
  343.  
  344.                if (k == 0)                     /* non covered, pm1 empty */
  345.               {
  346.                  k = count;                /* look for lowest adj term in pm-array */
  347.                  point = pm;
  348.               }
  349.                else
  350.               point = pm1;                 /* look for lowest adj term in pm1-array */
  351.  
  352.                adj0 = 255;                     /* max of 8-bit */
  353.                for (j=0; j<k; j++)             /* do for all in pm1/pm-array */
  354.               {
  355.                  memcpy(temp,(c+4+nspm*(1+*(point+j))),nspm);  /* pick an adj term */
  356.                  adji = adjacency(temp,b);                     /* obtain adjacency */
  357.  
  358.                  if (adji<=adj0)                        /* new lowest found */
  359.                 {
  360.                    adj0 = adji;                    /* update lowest */
  361.                    pos = *(point+j);               /* position of lowest adj term */
  362.                 }
  363.               }
  364.  
  365.                adj--;                            /* no. of adj terms in c-array */
  366.                *(c+1) = adj;                     /* adjacency after shrinking CPT */
  367.  
  368.                free(pm);                         /* free pointer */
  369.                free(pm1);
  370.  
  371.                /***
  372.             ***  SHRINK CPT (REMOVE 1 ADJACENT TERM FROM C-ARRAY), GENERATE NEW CPT, SSM
  373.             ***  AND TEST FOR COVERAGE BY FUNCTION
  374.             ***/
  375.  
  376.                memcpy((c+4+nspm*(1+pos)), (c+4+nspm*(2+pos)), nspm*(adj-pos));  /* shrink CPT */
  377.  
  378.                c = (unsigned char*) realloc(c, 4+nspm*(1+adj));   /* reduce space */
  379.                if (c==0)
  380.               {
  381.                  printf("Out of memory -- LOGMIN_G, *c\n");
  382.                  printf("Program terminated - 11\n");
  383.                  exit(0);
  384.               }
  385.  
  386.                d = cpt(c);                  /* generate CPT */
  387.                e = ssm(d);                  /* generate SSM */
  388.                m = topow(*(e+1));           /* no. of SSM terms */
  389.  
  390.                for (i=0; i<m; i++)          /* check SSM coverage by function */
  391.               {
  392.                  memcpy(temp, (e+4+nspm*i), nspm);  /* pick SSM term */
  393.                  test = exist(temp,a,ma);
  394.                  if (test == -1)                    /* SSM term not covered */
  395.                 break;
  396.               }
  397.  
  398.                /***
  399.             ***  SHRINKED SSM COVERED BY FUNCTION, REDUCE B-ARRAY
  400.             ***  AND SELECT SHRINKED CPT AS PRODUCT TERM
  401.             ***/
  402.  
  403.                if (test==0)                   /* SSM covered */
  404.               {
  405.                  if (m > 65536)                  /* too many SSM terms */
  406.                 {
  407.                    printf("Product Term Too Huge \n");
  408.                    printf("Program terminated \n");
  409.                    exit(0);
  410.                 }
  411.                  *(e+1) = (m-1) & mask8;         /* no. of SSM terms minus 1 */
  412.                  *(e+2) = (m-1)>>8 & mask8;
  413.                  b = reduce(e, b, i);     /* remove minterms covered from b-array */
  414.                  mb = *(b+2)<<8 | *(b+1); /* no. of minterms in b-array */
  415.  
  416.                  s = (unsigned char *) realloc(s, 4+n*(pterm+1));  /* more space */
  417.                  if (s==0)
  418.                 {
  419.                    printf("Out of memory -- LOGMIN_G, *s\n");
  420.                    printf("Program terminated - 12\n");
  421.                    exit(0);
  422.                 }
  423.                  memcpy ((s+4+n*pterm), d, n);      /* add shrinked CPT to soln array */
  424.                  pterm++;                           /* no. of product terms */
  425.  
  426.                  cover = 1;                         /* coverage status */
  427.                  free(e);                           /* free pointer */
  428.               }
  429.                free (d);                      /* free pointer */
  430.             }
  431.           }
  432.       free(c);                   /* free pointer */
  433.       }
  434.    *s = n;                           /* no. of variables */
  435.    *(s+1) = pterm & mask8;           /* no. of product terms in 2 bytes */
  436.    *(s+2) = pterm>>8 & mask8;
  437.  
  438.    free(temp);                       /* free pointer */
  439.    free(a);
  440.    free(b);
  441.  
  442.    return(s);                        /* return solution array */
  443. }
  444.  
  445.